package com.ddstation.common.util;

import static com.aliyun.oss.common.utils.IOUtils.safeClose;
import static com.aliyun.oss.common.utils.LogUtils.logException;
import static com.aliyun.oss.internal.OSSConstants.DEFAULT_BUFFER_SIZE;

import java.io.*;
import java.net.URL;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;

import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.*;
import com.ddstation.common.controller.ImgUploadController;
import com.ddstation.common.property.AliCloudOssProperties;

import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class AliCloudOssUtil {


	/**
	 * 根据Base64编码获取OssUrl
	 * @param bucketName
	 * @param base64
	 * @return
	 */
	public static String getUrlByBase64(String bucketName, String base64Str){
		// 创建OSS连接
		OSSClient ossClient = new OSSClient(AliCloudOssProperties.ossendpoint, AliCloudOssProperties.accessKeyId, AliCloudOssProperties.accessKeySecret);
		if(StringUtils.isBlank(bucketName)){
			bucketName = AliCloudOssProperties.bucketName;
		}
		try {
			InputStream inputStream1;
			String[] array = base64Str.split(",");
			int index = array[0].indexOf("/");
			int endIndex = array[0].indexOf(";");
			String endName = array[0].substring(index+1,endIndex);//获取文件后缀

			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			String today = sdf.format(new Date());

			String realUrl = ImgUploadController.userDir + "/" + today + "/" + RandomStrUtil.getRandStr(10) + "." + endName;

			byte[] bytes = new BASE64Decoder().decodeBuffer(array[1]); //将字符串转换为byte数组
			inputStream1 = new ByteArrayInputStream(bytes);
			ObjectMetadata metadata = new ObjectMetadata();
			metadata.setContentLength(inputStream1.available());
			ossClient.putObject(bucketName,realUrl, inputStream1, metadata);

			return realUrl;
		}catch (Exception e){
			logger.error("getUrlByBase64 error -> ",e);
		}
		return "";
	}

	/**
	 * 根据key获取图片文件Base64编码
	 * @param bucketName
	 * @param key
	 * @return
	 */
	public static String getBase64ByUrl(String bucketName, String key){
		try {
			// 创建OSS连接
			OSSClient ossClient = new OSSClient(AliCloudOssProperties.ossendpoint, AliCloudOssProperties.accessKeyId, AliCloudOssProperties.accessKeySecret);
			if(StringUtils.isBlank(bucketName)){
				bucketName = AliCloudOssProperties.bucketName;
			}
			// 获取文件对象
			//OSSObject ossObject = ossClient.getObject(bucketName, key);
			//定义file文件
			File file = new File("example-resize.jpg");

			// 缩放长边设定为800像素，短边自适应比例
			String style = "image/resize,l_800";
			GetObjectRequest request = new GetObjectRequest(bucketName, key);
			request.setProcess(style);
			ossClient.getObject(request, file);
			// 关闭OSSClient。
			ossClient.shutdown();
			//转码base64
			FileInputStream fin = new FileInputStream(file);
			byte[] bytes = new byte[fin.available()];
			fin.read(bytes);
			return Base64.getEncoder().encodeToString(bytes);

//			ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//			// 读取文件内容。
//			InputStream in = ossObject.getObjectContent();
//			//读取图片字节数组
//			byte[] buffer = new byte[1024];
//			//每次读取的字符串长度，如果为-1，代表全部读取完毕
//			int len = 0;
//			//使用一个输入流从buffer里把数据读取出来
//			while ((len = in.read(buffer)) != -1) {
//				//用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
//				outStream.write(buffer, 0, len);
//			}
//			//关闭输入流
//			in.close();
			// 关闭OSSClient。
//			ossClient.shutdown();
			//获取字节数组进行Base64编码
//			byte[] data = outStream.toByteArray();
//			BASE64Encoder encoder = new BASE64Encoder();
//			return encoder.encode(data);
		}catch (Exception e){
			logger.error("getBase64ByUrl error -> ",e);
			return key;//异常返回原key数据
		}
	}

	/**
	 * 获取原图  url
	 * @param bucketName
	 * @param key
	 * @return
	 */
    public static String getOriginImgUrl(String bucketName, String key) {

		OSSClient ossClient = new OSSClient(AliCloudOssProperties.ossendpoint, AliCloudOssProperties.accessKeyId, AliCloudOssProperties.accessKeySecret);

    	if(StringUtils.isBlank(bucketName))
    		bucketName = AliCloudOssProperties.bucketName;

        // 设置URL过期时间为1小时
        Date expiration = new Date(new Date().getTime() + AliCloudOssProperties.urlvaildtime);
        // 生成URL
        URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);

        // 关闭client
        ossClient.shutdown();

        return url.toString();
    }
    
	/**
	 * 获取缩略图原图  url
	 * @param bucketName
	 * @param key
	 * @return
	 */
    public static String getThumbImgUrl(String bucketName, String key, String tmbStrategy) {

    	try {
			// 样式转换
			// @100h to  image/resize,m_fixed,h_100
			String style = null;
			if(StringUtils.isNotBlank(tmbStrategy)) {
				style = "image/resize,m_fixed,{0}_{1}";

				// 缩比方向（横or纵）
				String direction = tmbStrategy.substring(tmbStrategy.length() - 1, tmbStrategy.length());
				// h or w check
				if(!"w".equalsIgnoreCase(direction) && !"h".equalsIgnoreCase(direction))
					direction = "h";
				// 缩放数量
				String amount = tmbStrategy.substring(1, tmbStrategy.length() - 1);
				try {
					int _amount = Integer.parseInt(amount);
					if(_amount == 0) amount = "100";
				} catch(Exception e) {
					amount = "100";
				}
				style = MessageFormat.format(style, direction, amount);
			}

			return getSelfStyleImgUrl(bucketName, key, style);	// 会抛出异常
		} catch (Exception e) {
    		logger.error("getThumbImgUrl error -> ",e);
    		return "";
		}
    }
    
    /**
     * 自定义样式图片
     * @param bucketName
     * @param key
     * @param style
     * @return
     */
    public static String getSelfStyleImgUrl(String bucketName, String key, String style) {
    	OSSClient ossClient = new OSSClient(AliCloudOssProperties.ossendpoint, AliCloudOssProperties.accessKeyId, AliCloudOssProperties.accessKeySecret);
    	
    	if(StringUtils.isBlank(bucketName))
    		bucketName = AliCloudOssProperties.bucketName;
    	
    	// 图片处理样式
//    	String style = "image/resize,m_fixed,h_100";  
    	
        // 设置URL过期时间为1小时
    	Date expiration = new Date(new Date().getTime() + AliCloudOssProperties.urlvaildtime);
        
    	// 生成URL
        GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, key, HttpMethod.GET);
        req.setExpiration(expiration);
        if(StringUtils.isNotBlank(style))
        	req.setProcess(style);
        URL signedUrl = ossClient.generatePresignedUrl(req);
        // 关闭client
        ossClient.shutdown();
        
        return signedUrl.toString();
    }
    
    /**
     * 把http url的图片上传至阿里oss
     * @param bucketName
     * @param key
     * @param _url
     * @return
     */
    public static String putObject(String bucketName, String key, String _url) {
    	
    	if (StringUtils.isBlank(bucketName)) {
    		bucketName = AliCloudOssProperties.bucketName;
    	}
    	
    	// 创建OSSClient实例
    	OSSClient ossClient = new OSSClient(AliCloudOssProperties.ossendpoint, AliCloudOssProperties.accessKeyId, AliCloudOssProperties.accessKeySecret);
    	// 上传图片文件
    	InputStream inputStream = null;
        try {
            URL url = new URL(_url);  
            inputStream = new BufferedInputStream(url.openStream());
            ossClient.putObject(bucketName, key, inputStream);
            return key;
        } catch (IOException e) {
        	logger.error(e.getMessage());
        } catch (Exception e) {
        	logger.error(e.getMessage());
        } finally {
        	if (inputStream != null) {
        		try {
        			inputStream.close();
        		} catch(IOException e) {
        			logger.error(e.getMessage());
        		}
			}
        	// 关闭client
        	ossClient.shutdown();
		}
    	return null;
    }
    
    /**
     * 上传文件
     * @param bucketName
     * @param key
     * @return
     */
    public static String putOSSObject(String bucketName, String key, File file) {

		OSSClient ossClient = new OSSClient(AliCloudOssProperties.ossendpoint, AliCloudOssProperties.accessKeyId, AliCloudOssProperties.accessKeySecret);
    	
    	if(StringUtils.isBlank(bucketName))
    		bucketName = AliCloudOssProperties.bucketName;
    	
    	if(StringUtils.isBlank(key) || !file.exists() || !file.isFile())
    		throw new RuntimeException("阿里云oss 上传参数不对！！！");
    	
    	ossClient.putObject(bucketName, key, file);
    	
    	// 设置URL过期时间为1小时
        Date expiration = new Date(new Date().getTime() + AliCloudOssProperties.urlvaildtime);
        // 生成URL
        URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);
    	// 关闭client
    	ossClient.shutdown();
    	
    	return url.toString();
    }
    
    /**
     * 下载文件
     * @param bucketName
     * @param key
     * @return
     */
    public static void getOSSObject(String bucketName, String key, File file) {

		OSSClient ossClient = new OSSClient(AliCloudOssProperties.ossendpoint, AliCloudOssProperties.accessKeyId, AliCloudOssProperties.accessKeySecret);
    	
    	if(StringUtils.isBlank(bucketName))
    		bucketName = AliCloudOssProperties.bucketName;
    	
    	if(StringUtils.isBlank(key))
    		throw new RuntimeException("阿里云oss 上传参数不对！！！");
    	
    	ossClient.getObject(new GetObjectRequest(bucketName, key), file);
    
    	// 关闭client
    	ossClient.shutdown();
    	
    }
    
    /**
     * 删除文件
     * @param bucketName
     * @param key
     * @return
     */
    public static void delOSSObject(String bucketName, String key) {

		OSSClient ossClient = new OSSClient(AliCloudOssProperties.ossendpoint, AliCloudOssProperties.accessKeyId, AliCloudOssProperties.accessKeySecret);
    	
    	if(StringUtils.isBlank(bucketName))
    		bucketName = AliCloudOssProperties.bucketName;
    	
    	if(StringUtils.isBlank(key))
    		throw new RuntimeException("阿里云oss 上传参数不对！！！");
    	
    	ossClient.deleteObject(bucketName, key);
    
    	// 关闭client
    	ossClient.shutdown();
    	
    }
    
	/**
	 * 判断文件是否存在
	 * @param bucketName
	 * @param key
	 * @return
	 */
    public static boolean isExist(String bucketName, String key) {
		
		OSSClient ossClient = new OSSClient(AliCloudOssProperties.ossendpoint, AliCloudOssProperties.accessKeyId, AliCloudOssProperties.accessKeySecret);
    	
    	if(StringUtils.isBlank(bucketName))
    		bucketName = AliCloudOssProperties.bucketName;
    	
    	boolean found = ossClient.doesObjectExist(bucketName, key);
        
        // 关闭client
        ossClient.shutdown();
        
        return found;
    }
    
    
    public static JSONObject getImgInfo(String bucketName, String key, String style) {
		
		OSSClient ossClient = new OSSClient(AliCloudOssProperties.ossendpoint, AliCloudOssProperties.accessKeyId, AliCloudOssProperties.accessKeySecret);
    	
    	if(StringUtils.isBlank(bucketName))
    		bucketName = AliCloudOssProperties.bucketName;
    	
    	GetObjectRequest request = new GetObjectRequest(bucketName, key);
    	request.setProcess(style);
    	
    	OSSObject ossObject = ossClient.getObject(request);
    	StringBuilder info = new StringBuilder();
    	JSONObject imgInfoJson = null;
    	try {
            byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
            
            while ((ossObject.getObjectContent().read(buffer)) != -1) {
            	info.append(new String(buffer));
            }
            
            if (info.length() > 0)
            	imgInfoJson = JSONObject.fromObject(info.toString());
            
        } catch (Exception ex) {
            logException("Cannot read object content stream: ", ex);
            logger.error(ex.getMessage());
        } finally {
            safeClose(ossObject.getObjectContent());
        }
    	
    	// 关闭client
        ossClient.shutdown();
        
        return imgInfoJson;
    }
    
    private static final Logger logger = LoggerFactory.getLogger(AliCloudOssUtil.class);
}
